﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using ExpertSystem.Domains;
using ExpertSystem.Interfaces;

namespace ExpertSystem.Views
{
    public partial class StepUpConsultation : Form
    {
        private AsyncRuleset _ruleset; 
        delegate void ASyncInvoce();

        private Dictionary<IRule,string > _activatedTule;
        private Stack<IVariable> s;
       
        private IVariable _variable;
        public StepUpConsultation(AsyncRuleset asyncRuleset = null)
        {
            InitializeComponent();
            _ruleset = asyncRuleset;
            _ruleset.GoalISFinded += GenerateOutput;
            _activatedTule = new Dictionary<IRule, string>();
        }

        private void ASyncInvocke()
        {
            _ruleset.StartConsultation();
        }

        private void groupBox1_Enter(object sender, EventArgs e)
        {

        }

        public void CastomizeView(object o, EventArgs eventArgs)
        {
            var v = (IVariable)o;
            
            dataGridView2.Invoke(new Action(() => this.VariablebindingSource.DataSource = _ruleset.StackSolution));
            label1.Invoke(new Action(() => this.label1.Text = v.Coments));
            _variable = v;
            ValuesbindingSource.DataSource = v;
            if (v != null)
            {
                switch (v.ValueType)
                {
                    case "String":
                        {
                            if (v.PosibleValues.Count > 0)
                            {
                                panel1.Invoke(
                                    new Action(
                                        () => panel1.Controls.Add(new ComboBox()
                                                                      {Parent = panel1, DataSource = ValuesbindingSource})));
                            }
                            else
                            {
                                panel1.Invoke(new Action(() => panel1.Controls.Add(new TextBox() { Parent = panel1 })));
                                
                            }
                            break;
                        }

                    case "Int":
                        {
                            
                            panel1.Invoke(new Action(() => panel1.Controls.Add(new TextBox() {Parent = panel1})));
                            panel1.Controls[0].KeyPress += IntInputControl;
                            break;
                        }

                }
            }
        }
        
        private void GenerateOutput(object o, EventArgs eventArgs)
        {
            listBox1.Invoke(new Action(() => this.listBox1.Items.Add("Всего активированно правил: " + _activatedTule.Count.ToString() + " ")));
            foreach (var rule in _activatedTule)
            {
                listBox1.Invoke(new Action(() => this.listBox1.Items.Add("Правило: " + rule.Key.Name + " ")));
                listBox1.Invoke(new Action(() => this.listBox1.Items.Add("     "+rule.Key.Comments)));
                listBox1.Invoke(new Action(() => this.listBox1.Items.Add("     " + "Вы ответили на вопросы:")));
                foreach (IConjunct conjunct in rule.Key.Conjuncts)
                {
                    foreach (IVariable variable in conjunct.Variables.Where(x => x.InputByUser))
                    {
                        listBox1.Invoke(new Action(() => this.listBox1.Items.Add("                " + variable.Comment+" введенное значение "+variable.Value)));
                    }
                }
                
                listBox1.Invoke(new Action(() => this.listBox1.Items.Add("                варианты: "+rule.Value)));
                listBox1.Invoke(new Action(() => this.listBox1.Items.Add("Значение целевой переменной:"+_ruleset.Variables.First(x => x.IsGoal).Value)));
            }

        }

        public void RuleActivated(object o,EventArgs eventArgs)
        {
            var r = (IRule) o;
            var vv = _ruleset.Variables;
            var p = vv.First(l => l.Name == "profile");
            var veriants = _ruleset.Ships.Where(x => x.Profile.ToString().Equals(vv.First(l => l.Name == "profile").ToString()) || (vv.First(l => l.Name == "profile").Value == null)).ToList();
            veriants = veriants.Where(x => (x.MaxAvto.Equals(vv.First(l => l.Name == "max_avto"))) || (vv.First(l => l.Name == "max_avto").Value == null)).ToList();
            veriants = veriants.Where(x => x.MaxChisl.Equals(vv.First(l => l.Name == "max_ch").Value) || (vv.First(l => l.Name == "max_ch").Value == null)).ToList();
            veriants = veriants.Where(x => x.Vodoizmeshenie.Equals(vv.First(l => l.Name == "vod_izm").Value) || (vv.First(l => l.Name == "vod_izm").Value == null)).ToList();
            string s = "";
            foreach (IShip veriant in veriants)
            {
                s += veriant.Name + " ";
            }
            _activatedTule.Add(r,s);
            
            //listBox1.Invoke(new Action(() => this.listBox1.Items.Add(r.Comments)));
        }

        private static void IntInputControl(object sender, KeyPressEventArgs keyEventArgs)
        {
            if (!char.IsNumber(keyEventArgs.KeyChar) && !char.IsControl(keyEventArgs.KeyChar))
            {
                keyEventArgs.Handled = true;
            }
        }

        private void StepUpConsultation_Shown(object sender, EventArgs e)
        {
            ASyncInvoce aSyncInvoce = ASyncInvocke;
            aSyncInvoce.BeginInvoke(null, null);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            if (_variable.PosibleValues.Count > 0)
            {
                _variable.Value = ValuesbindingSource.Current;
            }
            else
            {
                var textbox = (TextBox)panel1.Controls[0];
                switch (_variable.ValueType)
                {
                    case "String":
                        {
                            _variable.Value = textbox.Text;
                            break;
                        }
                    case "Int":
                        {
                            int values = 0;
                            int.TryParse(textbox.Text, out values);
                            _variable.Value = values;
                            break;
                        }

                }

            }
            if (_variable.Value.ToString().Length > 0)
            {
                _variable.VarInpeted.Set();
                panel1.Controls.Clear();
                dataGridView1.Invoke(
                new Action(() => RulebindingSource.DataSource = _ruleset.Rules.Where(x => x.Activated())));
                dataGridView1.Invalidate();
                dataGridView2.Invalidate();
            }
        }
    }
}
